package android.FiltrosJava;

//import java.awt.RenderingHints;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;

public class Rabiscos extends AbstractImageBasic{
	protected int distX = 22;
	protected int distY = 22;
	protected float lineSize = 20.0f;
	protected int rabiscoTipo = 0;
	protected AbstractImageBasic rabiscoTrans = null;
	
	public void setRabiscoTransformation(AbstractImageBasic rabiscoTransformation){
		rabiscoTrans = rabiscoTransformation;
	}
	
	public Rabiscos(int distanceX, int distanceY, float strokeSize){
		setRabiscos(distanceX, distanceY, strokeSize);
	}
	
	public void setHorizontalLines(){
		rabiscoTipo = 0;		
	}
	
	public void setVerticalLines(){
		rabiscoTipo = 1;		
	}
	
	public void setDiagonalLines(){
		rabiscoTipo = 2;
	}
	
	public void setRabiscos(int distanceX, int distanceY, float strokeSize){
		distX = distanceX;
		distY = distanceY;
		lineSize = strokeSize;
	}
	
	protected BufferedImage createDiagonalLines(BufferedImage src){
		int dimX = src.getWidth();
		int dimY = src.getHeight();			
		BufferedImage dst = criaImagemRGB(src);
		Graphics2D g2d = dst.createGraphics();
		//g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		g2d.setColor(Color.black);
		g2d.drawRect(0, 0, dimX, dimY);
		
		g2d.setStroke(new BasicStroke(lineSize, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));		
		g2d.setColor(Color.white);
		
		int maiorX = (int) (3 * dimX / distX);
		int maiorY = (int) (3 * dimY / distY);
		int[] vx = new int[maiorX];
		int[] vy = new int[maiorY];
		int p, p1, maxPX, maxPY;
		//calcula as coordanadas X		
		vx[0] = distX;
		p = 0;
		while (vx[p] < (dimX - 2 * distX)){
			p++;
			vx[p] = (int) (vx[p-1] + (distX * Math.random()));			
		}
		maxPX = p + 1;
		//calcula as coordanadas Y
		vy[0] = distY;
		p = 0;
		while (vy[p] < (dimY - 2 * distY)){
			p++;
			vy[p] = (int) (vy[p-1] + (distY * Math.random()));			
		}
		maxPY = p + 1;
		
		//combina as coordenadas
		int[][] top_right = new int[maxPX + maxPY][2];
		int[][] left_bottom = new int[maxPX + maxPY][2];
		
		for (int x = 0; x < maxPX; x++){
			top_right[x][0] = (int) (distY + (distY * Math.random()));
			top_right[x][1] = vx[x];
			
			left_bottom[maxPY + x][0] = dimY - top_right[x][0];
			left_bottom[maxPY + x][1] = vx[x];			
		}
		
		for (int y = 0; y < maxPY; y++){			
			left_bottom[y][0] = vy[y];
			left_bottom[y][1] = (int) (distX + (distX * Math.random()));
			
			top_right[maxPX + y][0] = vy[y];
			top_right[maxPX + y][1] = dimX - left_bottom[y][1];
		}
		
		//pintar...		
		boolean inverte = true;
		p = p1 = 0;
		while ((p < (maxPX + maxPY - 1)) && (p1 < (maxPX + maxPY - 1))){
			if (inverte)
				p1++;
			else
				p++;
						
			g2d.drawLine(top_right[p][1],top_right[p][0],left_bottom[p1][1],left_bottom[p1][0]);
			inverte = !inverte;
		}
		
		return dst;		
	}
	
	protected BufferedImage createVerticalLines(BufferedImage src){
		int dimX = src.getWidth();
		int dimY = src.getHeight();			
		BufferedImage dst = criaImagemRGB(src);
		Graphics2D g2d = dst.createGraphics();
		g2d.setColor(Color.black);
		g2d.drawRect(0, 0, dimX, dimY);
		
		g2d.setStroke(new BasicStroke(lineSize, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
		g2d.setColor(Color.white);
		
		int yi, xi, yf, xf;
		boolean inverte = false;
		yi = yf = distY;
		xi = xf = distX;		
		while (xi < (dimX - 2 * distX)){		
			if (inverte)
				xi = (int) (xf + (distX * Math.random()));
			else
				xf = (int) (xi + (distX * Math.random()));
				
			yi = (int) (distY + (distY * Math.random()));
			yf = dimY - yi;
			
			g2d.drawLine(xi, yi, xf, yf);			
			inverte = !inverte;
		}
		return dst;
	}
	
	protected BufferedImage createHorizontalLines(BufferedImage src){
		int dimX = src.getWidth();
		int dimY = src.getHeight();			
		BufferedImage dst = criaImagemRGB(src);
		Graphics2D g2d = dst.createGraphics();
		g2d.setColor(Color.black);
		g2d.drawRect(0, 0, dimX, dimY);
		
		g2d.setStroke(new BasicStroke(lineSize, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
		g2d.setColor(Color.white);
		
		int yi, xi, yf, xf;
		boolean inverte = false;
		yi = yf = distY;
		xi = xf = distX;		
		while (yi < (dimY - 2 * distY)){
			if (inverte)
				yi = (int) (yf + (distY * Math.random()));
			else
				yf = (int) (yi + (distY * Math.random()));
				
			xi = (int) (distX + (distX * Math.random()));
			xf = dimX - xi;
			
			g2d.drawLine(xi, yi, xf, yf);			
			inverte = !inverte;
		}
		return dst;
	}
	
	public BufferedImage applyFilter(BufferedImage src) {
		int dimX = src.getWidth();
		int dimY = src.getHeight();
		BufferedImage dst = null;
		
		switch (rabiscoTipo){
			case 0: dst = createHorizontalLines(src);
					break;
			case 1: dst = createVerticalLines(src);
					break;
			case 2: dst = createDiagonalLines(src);
					break;
		}
		
		WritableRaster raster_src = src.getRaster();
    	WritableRaster raster_dst = dst.getRaster();
    	int numBands = raster_src.getNumBands();
    	int[] imageData_src = new int[numBands];
    	int[] imageData_dst = new int[numBands];
    	int p, p1;
    	for ( int y = 0; y < dimY; y++ ) {
    		for ( int x = 0; x < dimX; x++ ) {
    			raster_src.getPixel(x,y,imageData_src);
    			raster_dst.getPixel(x,y,imageData_dst);    			
    			
    			if (imageData_dst[0] == 0){
    				imageData_dst[0] = 255;
    				imageData_dst[1] = 255;
    				imageData_dst[2] = 255;    				    				    				
    			}else{
    				p = imageData_dst[0]/255;
    				p1 = (1- p) * 255;
    				imageData_dst[0] = (int) (p * imageData_src[0] + p1);
    				imageData_dst[1] = (int) (p * imageData_src[1] + p1);
    				imageData_dst[2] = (int) (p * imageData_src[2] + p1);    				    				
    			}
    			
    			if (numBands > 3)
					imageData_dst[3] = imageData_src[3];
    			    			
    			raster_src.setPixel(x,y,imageData_dst);
    		}
    	}
    	
    	if (rabiscoTrans != null)
    		src = rabiscoTrans.applyFilter(src);
    	
    	dst = null;
    	return src;
	}
}
